<template>
  <div class="min-h-screen bg-gradient-to-br from-blue-50 to-purple-50 py-8">
    <div class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8">
      <!-- Header -->
      <div class="text-center mb-8">
        <h1 class="text-3xl font-bold text-gray-900 mb-4">
          <span class="text-gradient">URL 编码/解码</span>
        </h1>
        <p class="text-lg text-gray-600">对文本或 URL 进行 encodeURIComponent / decodeURIComponent 转换，支持 form-style 空格(+)、复制、下载和文件读取。</p>
      </div>

      <!-- Tool Container -->
      <div class="bg-white rounded-xl shadow-lg p-6">
        <!-- Mode Selection -->
        <div class="mb-6">
          <div class="flex space-x-4">
            <button
              @click="mode = 'encode'"
              :class="mode === 'encode' ? 'primary-button' : 'secondary-button'"
              class="flex-1"
            >
              编码 (文本 → URL 编码)
            </button>
            <button
              @click="mode = 'decode'"
              :class="mode === 'decode' ? 'primary-button' : 'secondary-button'"
              class="flex-1"
            >
              解码 (URL 编码 → 文本)
            </button>
          </div>
        </div>

        <!-- Input Area -->
        <div class="mb-6">
          <label class="block text-sm font-medium text-gray-700 mb-2">
            {{ mode === 'encode' ? '输入文本或 URL 片段' : '输入 URL 编码 字符串' }}
          </label>
          <textarea
            v-model="inputText"
            :placeholder="mode === 'encode' ? '请输入要编码的文本或 URL 片段...' : '请输入要解码的 URL 编码字符串...'
            "
            class="textarea-field h-28"
            @input="performConversion"
          ></textarea>
          <div class="mt-2 text-sm text-gray-500">字符数: {{ inputText.length }}</div>
        </div>

        <!-- Options -->
        <div class="mb-4 flex items-center space-x-6">
          <label class="inline-flex items-center space-x-2 text-sm text-gray-700">
            <input type="checkbox" v-model="formStyle" class="form-checkbox" />
            <span>表单风格 (空格 → +)</span>
          </label>
          <label class="inline-flex items-center space-x-2 text-sm text-gray-700">
            <input type="checkbox" v-model="autoDecodePlus" class="form-checkbox" />
            <span>解码时把 + 当作空格</span>
          </label>
        </div>

        <!-- Output Area -->
        <div class="mb-6">
          <label class="block text-sm font-medium text-gray-700 mb-2">
            {{ mode === 'encode' ? '编码结果' : '解码结果' }}
          </label>
          <textarea
            v-model="outputText"
            readonly
            class="textarea-field h-28 bg-gray-50"
            :placeholder="mode === 'encode' ? '编码结果将显示在这里...' : '解码后的文本将显示在这里...'
            "
          ></textarea>
          <div class="mt-2 flex justify-between items-center">
            <span class="text-sm text-gray-500">字符数: {{ outputText.length }}</span>
            <button @click="copyToClipboard" class="secondary-button text-sm py-2 px-4" :disabled="!outputText">
              {{ copied ? '已复制' : '复制结果' }}
            </button>
          </div>
        </div>

        <!-- Action Buttons -->
        <div class="flex flex-wrap gap-3">
          <button @click="performConversion" class="primary-button" :disabled="!inputText">
            {{ mode === 'encode' ? '编码' : '解码' }}
          </button>
          <button @click="clearAll" class="secondary-button">清空内容</button>
          <button @click="loadSample" class="secondary-button">加载示例</button>
        </div>

        <!-- File / Download -->
        <div class="mt-4 flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3">
          <div class="flex items-center space-x-3">
            <button @click="triggerFileInput" class="secondary-button">从文件读取</button>
            <input ref="fileInputRef" type="file" class="hidden" @change="handleFileChange" />
            <button @click="downloadResult" class="secondary-button" :disabled="!outputText">下载结果</button>
          </div>
        </div>

        <!-- Error Message -->
        <div v-if="errorMessage" class="mt-4 p-3 bg-red-50 border border-red-200 rounded-lg">
          <p class="text-red-600 text-sm">{{ errorMessage }}</p>
        </div>
      </div>

      <!-- Instructions -->
      <div class="mt-8 bg-white rounded-xl shadow-lg p-6">
        <h3 class="text-lg font-semibold text-gray-900 mb-4">使用说明</h3>
        <ul class="space-y-2 text-gray-600">
          <li>• 选择编码或解码模式</li>
          <li>• 输入要转换的文本或 URL 片段（支持自动实时转换）</li>
          <li>• 表单风格会把空格用 + 表示（常见于 application/x-www-form-urlencoded）</li>
          <li>• 使用“复制结果”按钮快速复制转换后的内容</li>
          <li>• 可从文件读取文本并转换，或下载结果为文本文件</li>
        </ul>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, watch } from 'vue'
import { useTools } from '@/composables/useTools'

const { copyToClipboard: toolsCopy, readFile, downloadFile } = useTools()

const mode = ref('encode')
const inputText = ref('')
const outputText = ref('')
const copied = ref(false)
const errorMessage = ref('')
const formStyle = ref(false) // 空格 -> +
const autoDecodePlus = ref(true) // 解码时把 + 当空格
const fileInputRef = ref(null)

const performConversion = () => {
  errorMessage.value = ''
  if (!inputText.value.trim()) {
    outputText.value = ''
    return
  }

  try {
    if (mode.value === 'encode') {
      let res = encodeURIComponent(inputText.value)
      if (formStyle.value) {
        // 将 %20 替换为 + 保持其他百分号编码
        res = res.replace(/%20/g, '+')
      }
      outputText.value = res
    } else {
      let s = inputText.value.trim()
      if (autoDecodePlus.value) {
        // 把 + 视作 空格
        s = s.replace(/\+/g, '%20')
      }
      // 解码可能会抛出 URIError
      outputText.value = decodeURIComponent(s)
    }
  } catch (err) {
    errorMessage.value = mode.value === 'encode' ? '编码失败：' + err.message : '解码失败：' + (err.message || '无效的编码')
    outputText.value = ''
  }
}

const copyToClipboard = async () => {
  if (!outputText.value) return
  try {
    const ok = await toolsCopy(outputText.value)
    if (ok) {
      copied.value = true
      setTimeout(() => (copied.value = false), 2000)
    } else {
    }
  } catch (err) {
  }
}

const clearAll = () => {
  inputText.value = ''
  outputText.value = ''
  errorMessage.value = ''
}

const loadSample = () => {
  if (mode.value === 'encode') {
    inputText.value = 'Hello World! 这是一个 URL 片段 /?q=测试&lang=zh'
  } else {
    inputText.value = 'Hello%20World%21%20%E8%BF%99%E6%98%AF%E4%B8%80%E4%B8%AA%20URL%20%E7%89%87%E6%AE%B5%20%2F%3Fq%3D%E6%B5%8B%E8%AF%95%26lang%3Dzh'
  }
  performConversion()
}

const triggerFileInput = () => {
  if (fileInputRef.value) fileInputRef.value.click()
}

const handleFileChange = async (e) => {
  const file = e.target.files && e.target.files[0]
  if (!file) return
  errorMessage.value = ''
  try {
    const text = await readFile(file)
    inputText.value = text
    performConversion()
  } catch (err) {
    errorMessage.value = '读取文件失败：' + (err.message || err)
  } finally {
    e.target.value = ''
  }
}

const downloadResult = () => {
  if (!outputText.value) return
  const filename = mode.value === 'encode' ? 'url-encoded.txt' : 'decoded.txt'
  downloadFile(outputText.value, filename, 'text/plain')
}

// 监听模式和输入变化
watch(mode, () => {
  clearAll()
})
watch(inputText, () => {
  performConversion()
})

useHead({
  title: 'URL 编码/解码 - 八八在线工具',
})
</script>
